/**********************************************************************************************/
/* FBL_Text_Stream.h																		  */
/*                                                                       					  */
/* Copyright Paradigma, 1993-2006                                        					  */
/* All Rights Reserved.                                                 					  */
/**********************************************************************************************/

#ifndef _FBL_Text_Stream_h
	#define _FBL_Text_Stream_h
#pragma once

// FBL:
#include <VShared/FBL/publ/Interfaces/FBL_I_IStream.h>
#include <VShared/FBL/publ/Interfaces/FBL_I_OStream.h>

#include <VShared/FBL/publ/Streams/FBL_Stream_Imp.h>

#include <VShared/FBL/publ/Util_Strings/FBL_ustdio.h>

#include <VShared/FBL/publ/Util_classes/FBL_StringConversion.h>

// FINAL:
#include <VShared/FBL/publ/Headers/FBL_pre_header.h>


/**********************************************************************************************/
FBL_Begin_Namespace


/**********************************************************************************************/
SMART_CLASS(Text_Stream);


/**********************************************************************************************/
// Text mode stream implementation based on UTF-16 encoding.
// (At least in the first implementation).
//
class Text_Stream : public Stream_Imp,
					public I_IStream,
					public I_OStream
{
	protected://////////////////////////////////////////////////////////////////////////////////
	
							Text_Stream( void );
							

	public://///////////////////////////////////////////////////////////////////////////////////


    // ---------------------
    // Input methods:

virtual I_IStream&          get(  void* 	inBuffer, 
								  ulong 	inHowMuch );

virtual I_IStream&          get(I_OStream& streamOut);
virtual I_IStream&			get( bool& outValue );
virtual I_IStream&			get( uchar& outValue );
virtual I_IStream&			get( char& outValue );
virtual I_IStream&			get( short& outValue );
virtual I_IStream&			get( ushort& outValue );
virtual I_IStream&			get( long& outValue );
virtual I_IStream&			get( ulong& outValue );
virtual I_IStream&			get( float& outValue );
virtual I_IStream&			get( double& outValue );
virtual I_IStream&			get( llong& outValue );
virtual I_IStream&			get( ullong& outValue );
virtual I_IStream&          get( UChar* inBuffer, tslen inChars );


	public://///////////////////////////////////////////////////////////////////////////////////

// Interface I_OStream

virtual I_OStream&          put(  const void* 	inBuffer, 
								  ulong 		inHowMuch );

virtual I_OStream&          put( I_IStream& stream_in );
virtual I_OStream&  		put( bool inValue );
virtual I_OStream&			put( uchar inValue );
virtual I_OStream&			put( char inValue );
virtual I_OStream&			put( short inValue );
virtual I_OStream&			put( ushort inValue );
virtual I_OStream&			put( long inValue );
virtual I_OStream&			put( ulong inValue );
virtual I_OStream&			put( float inValue );
virtual I_OStream&			put( double inValue );
virtual I_OStream&			put( llong inValue );
virtual I_OStream&			put( ullong inValue );
virtual I_OStream&			put( const UChar* inString, tslen inLen = -1 );
virtual I_OStream&			put( const char* inString, tslen inLen = - 1 );

	// Indent methods:

virtual void				IndentRight( void );
virtual void				IndentLeft( void );

virtual I_OStream&			WriteIndent( void );


	protected://////////////////////////////////////////////////////////////////////////////////

	// ---------------------
	// Derived classes API:

virtual void				Overflow( void );
virtual void				PutFailed( void );
virtual void				Underflow( void );
virtual void				GetFailed( void );


	protected://////////////////////////////////////////////////////////////////////////////////

		void				SkipSpaces( void );

		void				PutIt( const UChar* inCh, tslen inLen = -1 );

		UChar				GetChar( void );

							///	Turns read position back by once UChar.
		void				UnGet( void );

		template<class T, ulong kTStrMaxLen, class FN>
		T					StrToNum( FN inConvertFN );


	protected://////////////////////////////////////////////////////////////////////////////////

		ulong 				mCurrIndent;

static	UChar				sIndents[];

};


/**********************************************************************************************/
template<class T, ulong kTStrMaxLen, class FN>
T Text_Stream::StrToNum( FN inConvertFN )
{
	SkipSpaces();

	UChar c = 0;
	UChar buf[kTStrMaxLen + 1];
	UChar *p = buf;

	c = GetChar();
	if( vu_isdigit(c) || c == UChar('-') || c == UChar('+') )
	{
		do
		{
			*p++ = c;
		}
		while( !IsDelim(c = GetChar()) && ulong(p - buf) < kTStrMaxLen );
	}
	else
	{
		// Wrong input format
		*p = 0;
		throw xExternalError(ERR_STREAM_READ_ERROR, "" );
	}

	*p = 0;
	return static_cast<T>(inConvertFN(buf));
}


/**********************************************************************************************/
FBL_End_Namespace


/**********************************************************************************************/
#include <VShared/FBL/publ/Headers/FBL_post_header.h>


/**********************************************************************************************/
#endif // _FBL_Text_Stream_h
